'use client' import type { FC, SVGProps } from 'react' import React, { useEffect, useMemo } from 'react' import { usePathname } from 'next/navigation' import useSWR from 'swr' import { useTranslation } from 'react-i18next' import { useBoolean } from 'ahooks' import { Cog8ToothIcon, DocumentTextIcon, PaperClipIcon, } from '@heroicons/react/24/outline' import { Cog8ToothIcon as Cog8ToothSolidIcon, // CommandLineIcon as CommandLineSolidIcon, DocumentTextIcon as DocumentTextSolidIcon, } from '@heroicons/react/24/solid' import { RiApps2AddLine, RiBookOpenLine, RiInformation2Line } from '@remixicon/react' import s from './style.module.css' import classNames from '@/utils/classnames' import { fetchDatasetDetail, fetchDatasetRelatedApps } from '@/service/datasets' import type { RelatedAppResponse } from '@/models/datasets' import AppSideBar from '@/app/components/app-sidebar' import Loading from '@/app/components/base/loading' import DatasetDetailContext from '@/context/dataset-detail' import { DataSourceType } from '@/models/datasets' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import { LanguagesSupported } from '@/i18n/language' import { useStore } from '@/app/components/app/store' import { getLocaleOnClient } from '@/i18n' import { useAppContext } from '@/context/app-context' import Tooltip from '@/app/components/base/tooltip' import LinkedAppsPanel from '@/app/components/base/linked-apps-panel' import { GetDatasetAuth } from '@/app/(commonLayout)/datasets/Container' export type IAppDetailLayoutProps = { children: React.ReactNode params: { datasetId: string } } const TargetIcon = ({ className }: SVGProps) => { return } const TargetSolidIcon = ({ className }: SVGProps) => { return } type IExtraInfoProps = { isMobile: boolean relatedApps?: RelatedAppResponse expand: boolean } const ExtraInfo = ({ isMobile, relatedApps, expand }: IExtraInfoProps) => { const locale = getLocaleOnClient() const [isShowTips, { toggle: toggleTips, set: setShowTips }] = useBoolean(!isMobile) const { t } = useTranslation() const hasRelatedApps = relatedApps?.data && relatedApps?.data?.length > 0 const relatedAppsTotal = relatedApps?.data?.length || 0 useEffect(() => { setShowTips(!isMobile) }, [isMobile, setShowTips]) return
{hasRelatedApps && ( <> {!isMobile && ( } >
{relatedAppsTotal || '--'} {t('common.datasetMenus.relatedApp')}
)} {isMobile &&
{relatedAppsTotal || '--'}
} )} {!hasRelatedApps && !expand && (
{t('common.datasetMenus.emptyTip')}
{t('common.datasetMenus.viewDoc')}
} >
{t('common.datasetMenus.noRelatedApp')}
)} } const DatasetDetailLayout: FC = (props) => { const { children, params: { datasetId }, } = props const pathname = usePathname() const hideSideBar = /documents\/create$/.test(pathname) const { t } = useTranslation() const { isCurrentWorkspaceDatasetOperator } = useAppContext() const media = useBreakpoints() const isMobile = media === MediaType.mobile const { data: datasetRes, error, mutate: mutateDatasetRes } = useSWR({ url: 'fetchDatasetDetail', datasetId, }, apiParams => fetchDatasetDetail(apiParams.datasetId)) const { isCreate, isEdit, isOperation } = GetDatasetAuth(datasetRes) const { data: relatedApps } = useSWR({ action: 'fetchDatasetRelatedApps', datasetId, }, apiParams => fetchDatasetRelatedApps(apiParams.datasetId)) const navigation = useMemo(() => { const baseNavigation = [ // { name: 'api & webhook', href: `/datasets/${datasetId}/api`, icon: CommandLineIcon, selectedIcon: CommandLineSolidIcon }, // { name: t('common.datasetMenus.settings'), href: `/datasets/${datasetId}/settings`, icon: Cog8ToothIcon, selectedIcon: Cog8ToothSolidIcon }, ] if (isEdit) { baseNavigation.unshift({ name: t('common.datasetMenus.hitTesting'), href: `/datasets/${datasetId}/hitTesting`, icon: TargetIcon, selectedIcon: TargetSolidIcon, }) baseNavigation.push({ name: t('common.datasetMenus.settings'), href: `/datasets/${datasetId}/settings`, icon: Cog8ToothIcon, selectedIcon: Cog8ToothSolidIcon, }) } if (datasetRes?.provider !== 'external') { baseNavigation.unshift({ name: t('common.datasetMenus.documents'), href: `/datasets/${datasetId}/documents`, icon: DocumentTextIcon, selectedIcon: DocumentTextSolidIcon, }) } return baseNavigation }, [datasetRes?.provider, datasetId, t]) useEffect(() => { if (datasetRes) document.title = `${datasetRes.name || 'Dataset'} - Dify` }, [datasetRes]) const setAppSiderbarExpand = useStore(state => state.setAppSiderbarExpand) useEffect(() => { const localeMode = localStorage.getItem('app-detail-collapse-or-expand') || 'expand' const mode = isMobile ? 'collapse' : 'expand' setAppSiderbarExpand(isMobile ? mode : localeMode) }, [isMobile, setAppSiderbarExpand]) if (!datasetRes && !error) return return (
{!hideSideBar && : undefined} iconType={datasetRes?.data_source_type === DataSourceType.NOTION ? 'notion' : 'dataset'} />} mutateDatasetRes(), }}>
{children}
) } export default React.memo(DatasetDetailLayout)